#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""量子金融分析系统 - 核心接口集成层
负责与腾讯平台进行通信的统一接口, 提供高级API调用功能
支持多账户管理"""

import os
import sys
import json
import time
import threading
import traceback
from datetime import datetime

# 添加项目根目录到系统路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

# 临时模拟Logger类，解决导入问题
class Logger:
    @staticmethod
    def init_logger():
        pass
    
    @staticmethod
    def log_info(msg):
        print(f"INFO: {msg}")
        
    @staticmethod
    def log_warning(msg):
        print(f"WARNING: {msg}")
        
    @staticmethod
    def log_error(msg):
        print(f"ERROR: {msg}")

# 临时模拟FileUtils类，解决导入问题
class FileUtils:
    @staticmethod
    def read_file(file_path):
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception as e:
            print(f"ERROR: 读取文件失败: {file_path}, 错误: {str(e)}")
            return None
    
    @staticmethod
    def write_file(file_path, content):
        try:
            # 确保目录存在
            dir_path = os.path.dirname(file_path)
            if dir_path and not os.path.exists(dir_path):
                os.makedirs(dir_path)
            
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            return True
        except Exception as e:
            print(f"ERROR: 写入文件失败: {file_path}, 错误: {str(e)}")
            return False

# 临时模拟ExceptionHandler类，解决导入问题
class ExceptionHandler:
    @staticmethod
    def handle_exceptions(func):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                print(f"ERROR: 执行函数 {func.__name__} 时发生异常: {str(e)}")
                print(f"ERROR: 异常堆栈: {traceback.format_exc()}")
                return None
        return wrapper

from tencent_api_connector import TencentAPIConnector
from alipay_api_connector import AlipayAPIConnector
from utils.account_manager import account_manager

class APIIntegration:
    """核心接口集成层
    提供与腾讯证券交易平台通信的高级接口，封装认证、行情获取、交易操作等功能
    支持多账户管理"""
    
    # 接口配置
    API_CONFIG = {
        "MAX_CONCURRENT_CALLS": 5,  # 最大并发调用数
        "RATE_LIMIT_INTERVAL": 1.0,  # 接口调用频率限制(秒)
        "API_TIMEOUT": 30,  # API调用超时时间(秒)
        "RETRY_COUNT": 3,  # 失败重试次数
        "RETRY_INTERVAL": 1.5  # 重试间隔(秒)
    }
    
    def __init__(self):
        """初始化核心接口集成层"""
        # 账户管理
        self.current_account_id = "default"  # 默认账户ID
        
        # 为每个账户维护独立的API连接器实例
        self.api_connectors = {}
        
        # 初始化默认账户的API连接器
        self._get_or_create_connector(self.current_account_id)
        
        # 并发控制
        self.call_semaphore = threading.Semaphore(self.API_CONFIG["MAX_CONCURRENT_CALLS"])
        self.last_call_time = 0
        self.rate_limit_lock = threading.Lock()
        
        # 数据缓存
        self.cache = {}
        self.cache_lock = threading.Lock()
        self.cache_timeout = 60  # 缓存超时时间(秒)
        
        # 状态追踪
        self.is_initialized = False
        self.health_status = {
            "api_connected": False,
            "last_health_check": None,
            "error_count": 0
        }
    
    def _get_or_create_connector(self, account_id):
        """获取或创建指定账户的API连接器实例
        
        Args:
            account_id (str): 账户ID
        
        Returns:
            相应平台的API连接器实例
        """
        if account_id not in self.api_connectors:
            # 检查账户管理器中是否存在该账户
            account = account_manager.get_account(account_id)
            if not account and account_id != "default":
                Logger.log_error(f"账户 {account_id} 不存在")
                return None
            
            # 根据平台类型创建相应的API连接器实例
            platform = "tencent"  # 默认使用腾讯平台
            if account:
                platform = account.get('platform', 'tencent')
            
            if platform == 'tencent':
                self.api_connectors[account_id] = TencentAPIConnector(account_id=account_id)
                Logger.log_info(f"为账户 {account_id} 创建了腾讯API连接器实例")
            elif platform == 'alipay':
                self.api_connectors[account_id] = AlipayAPIConnector(account_id=account_id)
                Logger.log_info(f"为账户 {account_id} 创建了支付宝API连接器实例")
            else:
                # 未知平台，默认使用腾讯平台
                self.api_connectors[account_id] = TencentAPIConnector(account_id=account_id)
                Logger.log_warning(f"未知平台类型 {platform}，默认使用腾讯平台")
        
        return self.api_connectors[account_id]
    
    def switch_account(self, account_id):
        """切换当前活动账户
        
        Args:
            account_id (str): 要切换到的账户ID
        
        Returns:
            bool: 切换是否成功
        """
        # 验证账户是否存在
        if account_id not in account_manager.get_all_accounts() and account_id != "default":
            Logger.log_error(f"账户 {account_id} 不存在")
            return False
        
        # 获取或创建该账户的API连接器
        connector = self._get_or_create_connector(account_id)
        if not connector:
            return False
        
        # 切换当前账户
        self.current_account_id = account_id
        Logger.log_info(f"已切换到账户 {account_id}")
        
        # 重置初始化状态，需要为新账户重新初始化
        self.is_initialized = False
        
        return True
    
    def get_current_account_id(self):
        """获取当前活动账户ID
        
        Returns:
            str: 当前账户ID
        """
        return self.current_account_id
    
    def get_current_connector(self):
        """获取当前活动账户的API连接器
        
        Returns:
            TencentAPIConnector: 当前活动账户的API连接器实例
        """
        return self._get_or_create_connector(self.current_account_id)
    
    @ExceptionHandler.handle_exceptions
    def initialize(self, account_id=None):
        """初始化接口集成层，可指定账户ID
        
        Args:
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            bool: 初始化是否成功
        """
        # 如果指定了账户ID，先切换到该账户
        if account_id and account_id != self.current_account_id:
            if not self.switch_account(account_id):
                return False
        
        if self.is_initialized:
            Logger.log_info(f"账户 {self.current_account_id} 的API集成层已初始化")
            return True
        
        try:
            # 检查API配置
            if not self._check_api_config():
                Logger.log_error(f"账户 {self.current_account_id} 的API配置检查失败，无法初始化接口集成层")
                return False
            
            # 获取当前账户的连接器
            current_connector = self.get_current_connector()
            if not current_connector:
                Logger.log_error(f"无法获取账户 {self.current_account_id} 的API连接器")
                return False
            
            # 进行API认证
            if not current_connector.authenticate():
                Logger.log_error(f"账户 {self.current_account_id} 的API认证失败，无法初始化接口集成层")
                return False
            
            # 更新健康状态
            self.health_status["api_connected"] = True
            self.health_status["last_health_check"] = datetime.now()
            
            self.is_initialized = True
            Logger.log_info(f"账户 {self.current_account_id} 的API集成层初始化成功")
            return True
        except Exception as e:
            Logger.log_error(f"账户 {self.current_account_id} 的API集成层初始化异常: {str(e)}")
            self.health_status["error_count"] += 1
            return False
    
    def _check_api_config(self, account_id=None):
        """检查API配置是否完整
        
        Args:
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            bool: 配置是否完整
        """
        # 获取指定账户的连接器
        connector = self._get_or_create_connector(account_id or self.current_account_id)
        if not connector:
            return False
        
        # 检查API凭证
        if not connector.api_key or not connector.api_secret:
            Logger.log_warning(f"账户 {self.current_account_id} 的API凭证不完整，尝试从配置文件加载")
            connector.load_api_credentials()
            
            # 再次检查
            if not connector.api_key or not connector.api_secret:
                Logger.log_error(f"无法获取账户 {self.current_account_id} 的有效API凭证")
                return False
        
        # 检查API连接
        try:
            # 这里可以添加一个轻量级的API调用进行连通性测试
            test_stock_code = "sh600000"
            test_data = connector.get_market_data(test_stock_code)
            if test_data and test_stock_code in test_data:
                Logger.log_info(f"账户 {self.current_account_id} 的API连通性测试通过")
                return True
            else:
                Logger.log_error(f"账户 {self.current_account_id} 的API连通性测试失败")
                return False
        except Exception as e:
            Logger.log_error(f"账户 {self.current_account_id} 的API连通性测试异常: {str(e)}")
            return False
    
    def _enforce_rate_limit(self):
        """强制执行API调用频率限制"""
        with self.rate_limit_lock:
            current_time = time.time()
            elapsed = current_time - self.last_call_time
            
            if elapsed < self.API_CONFIG["RATE_LIMIT_INTERVAL"]:
                # 需要等待到频率限制间隔
                wait_time = self.API_CONFIG["RATE_LIMIT_INTERVAL"] - elapsed
                time.sleep(wait_time)
                
            # 更新最后调用时间
            self.last_call_time = time.time()
    
    @ExceptionHandler.handle_exceptions
    def get_market_data(self, stock_codes, use_cache=True, account_id=None):
        """获取股票行情数据
        
        Args:
            stock_codes (str or list): 股票代码或股票代码列表
            use_cache (bool): 是否使用缓存数据
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 行情数据
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 标准化输入
        if isinstance(stock_codes, str):
            stock_codes = [stock_codes]
        
        # 使用缓存
        if use_cache:
            cached_data = self._get_cached_market_data(stock_codes)
            if cached_data and len(cached_data) == len(stock_codes):
                return cached_data
        
        # 获取指定账户的连接器
        target_account = account_id or self.current_account_id
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.get_market_data(stock_codes)
        
        # 更新缓存
        if result and use_cache:
            self._update_market_data_cache(result)
        
        return result
    
    def _get_cached_market_data(self, stock_codes):
        """从缓存获取行情数据
        
        Args:
            stock_codes (list): 股票代码列表
        
        Returns:
            dict: 缓存的行情数据，如果缓存不存在或已过期则返回None
        """
        with self.cache_lock:
            result = {}
            current_time = time.time()
            
            for code in stock_codes:
                cache_key = f"market_data_{code}"
                
                if cache_key in self.cache:
                    cached_item = self.cache[cache_key]
                    # 检查缓存是否过期
                    if current_time - cached_item["timestamp"] < self.cache_timeout:
                        result[code] = cached_item["data"]
                    else:
                        # 缓存过期，删除
                        del self.cache[cache_key]
            
            return result if len(result) > 0 else None
    
    def _update_market_data_cache(self, market_data):
        """更新行情数据缓存
        
        Args:
            market_data (dict): 行情数据
        """
        with self.cache_lock:
            current_time = time.time()
            
            for code, data in market_data.items():
                cache_key = f"market_data_{code}"
                self.cache[cache_key] = {
                    "data": data,
                    "timestamp": current_time
                }
    
    @ExceptionHandler.handle_exceptions
    def place_order(self, stock_code, order_type, quantity, price, account_id=None):
        """下单交易
        
        Args:
            stock_code (str): 股票代码
            order_type (str): 订单类型，'buy' 或 'sell'
            quantity (int): 交易数量
            price (float): 交易价格
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 下单结果
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 验证参数
        if not stock_code or order_type not in ['buy', 'sell'] or quantity <= 0 or price <= 0:
            Logger.log_error(f"下单参数验证失败: {stock_code}, {order_type}, {quantity}, {price}")
            return None
        
        # 获取指定账户的连接器
        target_account = account_id or self.current_account_id
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.place_order(stock_code, order_type, quantity, price)
        
        # 记录交易日志
        if result and result.get("success", False):
            Logger.log_info(f"账户 {target_account} 下单成功: {stock_code} {order_type} {quantity}股 @ {price}")
        
        return result
    
    @ExceptionHandler.handle_exceptions
    def query_order(self, order_id, account_id=None):
        """查询订单状态
        
        Args:
            order_id (str): 订单ID
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 订单信息
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 验证参数
        if not order_id:
            Logger.log_error("查询订单参数验证失败: 订单ID为空")
            return None
        
        # 获取指定账户的连接器
        target_account = account_id or self.current_account_id
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.query_order(order_id)
        
        return result
    
    @ExceptionHandler.handle_exceptions
    def cancel_order(self, order_id, account_id=None):
        """撤销订单
        
        Args:
            order_id (str): 订单ID
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 撤销结果
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 验证参数
        if not order_id:
            Logger.log_error("撤销订单参数验证失败: 订单ID为空")
            return None
        
        # 获取指定账户的连接器
        target_account = account_id or self.current_account_id
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.cancel_order(order_id)
        
        return result
    
    @ExceptionHandler.handle_exceptions
    def get_account_info(self, use_cache=True, account_id=None):
        """获取账户信息
        
        Args:
            use_cache (bool): 是否使用缓存数据
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 账户信息
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 使用缓存
        target_account = account_id or self.current_account_id
        cache_key = f"account_info_{target_account}"
        if use_cache:
            with self.cache_lock:
                if cache_key in self.cache:
                    cached_item = self.cache[cache_key]
                    # 检查缓存是否过期
                    if time.time() - cached_item["timestamp"] < self.cache_timeout:
                        return cached_item["data"]
        
        # 获取指定账户的连接器
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.get_account_info()
        
        # 处理响应数据格式
        if result and isinstance(result, dict):
            # 检查是否有success字段和account_info字段
            if result.get("success") and "account_info" in result:
                processed_result = result["account_info"]
            else:
                # 如果不是标准格式，直接返回原始结果
                processed_result = result
        else:
            processed_result = result
        
        # 更新缓存
        if processed_result and use_cache:
            with self.cache_lock:
                self.cache[cache_key] = {
                    "data": processed_result,
                    "timestamp": time.time()
                }
        
        return processed_result
    
    @ExceptionHandler.handle_exceptions
    def get_positions(self, use_cache=True, account_id=None):
        """获取持仓信息
        
        Args:
            use_cache (bool): 是否使用缓存数据
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 持仓信息
        """
        # 确保初始化完成
        if not self.is_initialized:
            if not self.initialize(account_id):
                return None
        
        # 使用缓存
        target_account = account_id or self.current_account_id
        cache_key = f"positions_{target_account}"
        if use_cache:
            with self.cache_lock:
                if cache_key in self.cache:
                    cached_item = self.cache[cache_key]
                    # 检查缓存是否过期
                    if time.time() - cached_item["timestamp"] < self.cache_timeout:
                        return cached_item["data"]
        
        # 获取指定账户的连接器
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return None
        
        # 执行API调用，使用信号量控制并发
        with self.call_semaphore:
            self._enforce_rate_limit()
            result = connector.get_positions()
        
        # 处理响应数据格式
        if result and isinstance(result, dict):
            # 检查是否有success字段和positions字段
            if result.get("success") and "positions" in result:
                processed_result = result["positions"]
            else:
                # 如果不是标准格式，直接返回原始结果
                processed_result = result
        else:
            processed_result = result
        
        # 更新缓存
        if processed_result and use_cache:
            with self.cache_lock:
                self.cache[cache_key] = {
                    "data": processed_result,
                    "timestamp": time.time()
                }
        
        return processed_result
    
    @ExceptionHandler.handle_exceptions
    def health_check(self, account_id=None):
        """执行健康检查
        
        Args:
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            dict: 健康检查结果
        """
        try:
            # 获取指定账户的连接器
            target_account = account_id or self.current_account_id
            connector = self._get_or_create_connector(target_account)
            if not connector:
                return {
                    "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "api_connected": False,
                    "api_functional": False,
                    "error_count": self.health_status["error_count"],
                    "error_message": f"无法获取账户 {target_account} 的API连接器"
                }
            
            # 检查API连接状态
            api_connected = connector.is_authenticated
            if not api_connected:
                # 尝试重新认证
                api_connected = connector.authenticate()
            
            # 更新健康状态
            self.health_status["api_connected"] = api_connected
            self.health_status["last_health_check"] = datetime.now()
            
            # 进行简单的API调用测试
            test_result = connector.get_market_data("sh600000")
            api_functional = test_result is not None
            
            return {
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "api_connected": api_connected,
                "api_functional": api_functional,
                "error_count": self.health_status["error_count"],
                "account_id": target_account
            }
        except Exception as e:
            Logger.log_error(f"账户 {self.current_account_id} 的健康检查异常: {str(e)}")
            self.health_status["error_count"] += 1
            return {
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "api_connected": False,
                "api_functional": False,
                "error_count": self.health_status["error_count"],
                "error_message": str(e),
                "account_id": self.current_account_id
            }
    
    @ExceptionHandler.handle_exceptions
    def clear_cache(self):
        """清除所有缓存"""
        with self.cache_lock:
            self.cache.clear()
            Logger.log_info("已清除API集成层缓存")
    
    @ExceptionHandler.handle_exceptions
    def save_api_credentials(self, api_key, api_secret, account_id=None):
        """保存API凭证
        
        Args:
            api_key (str): API密钥
            api_secret (str): API密钥密码
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            bool: 保存是否成功
        """
        # 获取指定账户的连接器
        target_account = account_id or self.current_account_id
        connector = self._get_or_create_connector(target_account)
        if not connector:
            return False
        
        result = connector.save_api_credentials(api_key, api_secret)
        
        # 如果保存成功，重新初始化
        if result:
            self.is_initialized = False
            self.initialize(target_account)
        
        return result
    
    @ExceptionHandler.handle_exceptions
    def set_proxy(self, proxy_url, account_id=None):
        """设置HTTP代理
        
        Args:
            proxy_url (str): 代理服务器URL
            account_id (str, optional): 账户ID，如果未指定则使用当前账户
        
        Returns:
            bool: 设置是否成功
        """
        try:
            # 获取指定账户的连接器
            target_account = account_id or self.current_account_id
            connector = self._get_or_create_connector(target_account)
            if not connector:
                return False
            
            connector.set_proxy(proxy_url)
            # 重新初始化以应用代理设置
            self.is_initialized = False
            return self.initialize(target_account)
        except Exception as e:
            Logger.log_error(f"为账户 {self.current_account_id} 设置代理失败: {str(e)}")
            return False

# 创建全局API集成实例，方便其他模块直接使用
api_integration = APIIntegration()

# 模块初始化完成后的提示
if __name__ == "__main__":
    Logger.log_info("API集成模块加载完成，支持多账户管理功能")